/*
 * Copyright (c) 2006-2021, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2024-05-06     liuchao       the first version
 */
#define LOG_TAG "cli"
#include "configuration.h"
#include <stdio.h>
#include <ulog.h>
#include <stdlib.h>
#include <rtthread.h>
#include <rtdevice.h>

void configuration_list_cli()
{
    for (int i = CONFIGURATION_START; i < CONFIGRATION_END; i++)
    {
        printf("%-32s: %d\n", configuration_name(i), i);
    }
}
MSH_CMD_EXPORT_ALIAS(configuration_list_cli, configuration_list, List configurations);

void configuration_set_cli(int argc, char** argv)
{
    if (argc != 3)
    {
        printf("<configuration> <value>\n");
        return;
    }
    configuration_e configuration = atoi(argv[1]);
    if (configuration < CONFIGURATION_START || configuration >= CONFIGRATION_END)
    {
        printf("Invalid configuration: %d\n", configuration);
        return;
    }
    configuration_type_e t = configuration_type(configuration);
    if (t == CONFIGURATION_TYPE_UINT32)
    {
        configuration_set_uint32(configuration, atoi(argv[2]));
    }
    else if (t == CONFIGURATION_TYPE_FLOAT)
    {
        configuration_set_float(configuration, atof(argv[2]));
    }
    else
    {
        configuration_set(configuration, argv[2]);
    }
}
MSH_CMD_EXPORT_ALIAS(configuration_set_cli, configuration_set, Set configuration)

void configuration_get_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("<configuration>\n");
        return;
    }
    configuration_e configuration = atoi(argv[1]);
    if (configuration < CONFIGURATION_START || configuration >= CONFIGRATION_END)
    {
        printf("Invalid configuration: %d\n", configuration);
        return;
    }
    configuration_type_e t = configuration_type(configuration);
    if (t == CONFIGURATION_TYPE_UINT32)
    {
        printf("%lu\n", configuration_get_uint32(configuration));
    }
    else if (t == CONFIGURATION_TYPE_FLOAT)
    {
        printf("%f\n", configuration_get_float(configuration));
    }
    else
    {
        printf("%s\n", configuration_get(configuration));
    }
}
MSH_CMD_EXPORT_ALIAS(configuration_get_cli, configuration_get, Get configuration)

void configuration_dump_cli()
{
    configuration_dump();
}
MSH_CMD_EXPORT_ALIAS(configuration_dump_cli, configuration_dump, Dump configuration)

void set_mqtt_host(int argc, char** argv)
{
    if (argc == 2)
    {
        if (configuration_set(CONFIGURATION_MQTT_HOST, argv[1]) == RT_EOK)
        {
            printf("success\n");
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT(set_mqtt_host, Write mqtt host)

void get_mqtt_host()
{
    const char* value = configuration_get(CONFIGURATION_MQTT_HOST);
    printf("%s\n", value);
}
MSH_CMD_EXPORT(get_mqtt_host, Read mqtt host)

void set_mqtt_port(int argc, char** argv)
{
    if (argc == 2)
    {
        if (configuration_set(CONFIGURATION_MQTT_PORT, argv[1]) == RT_EOK)
        {
            printf("success\n");
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT(set_mqtt_port, Write mqtt port)

void get_mqtt_port()
{
    const char* value = configuration_get(CONFIGURATION_MQTT_PORT);
    printf("%s\n", value);
}
MSH_CMD_EXPORT(get_mqtt_port, Read mqtt port)

void set_mqtt_client_id(int argc, char** argv)
{
    if (argc == 2)
    {
        if (configuration_set(CONFIGURATION_MQTT_CLIENT_ID, argv[1]) == RT_EOK)
        {
            printf("success\n");
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT(set_mqtt_client_id, Write mqtt client id)

void get_mqtt_client_id()
{
    const char* value = configuration_get(CONFIGURATION_MQTT_CLIENT_ID);
    printf("%s\n", value);
}
MSH_CMD_EXPORT(get_mqtt_client_id, Read mqtt client id)

void set_mqtt_user_name(int argc, char** argv)
{
    if (argc == 2)
    {
        if (configuration_set(CONFIGURATION_MQTT_USER_NAME, argv[1]) == RT_EOK)
        {
            printf("success\n");
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT(set_mqtt_user_name, Write mqtt user name)

void get_mqtt_user_name()
{
    const char* value = configuration_get(CONFIGURATION_MQTT_USER_NAME);
    printf("%s\n", value);
}
MSH_CMD_EXPORT(get_mqtt_user_name, Read mqtt user name)

void set_mqtt_passwd(int argc, char** argv)
{
    if (argc == 2)
    {
        if (configuration_set(CONFIGURATION_MQTT_PASSWD, argv[1]) == RT_EOK)
        {
            printf("success\n");
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT(set_mqtt_passwd, Write mqtt password)

void get_mqtt_passwd()
{
    const char* value = configuration_get(CONFIGURATION_MQTT_PASSWD);
    printf("%s\n", value);
}
MSH_CMD_EXPORT(get_mqtt_passwd, Read mqtt password)

void set_sensor_oil_pressure_baseline(int argc, char** argv)
{
    if (argc == 2)
    {
        rt_uint32_t v = atoi(argv[1]);
        if (configuration_set_uint32(CONFIGURATION_SENSOR_OIL_PRESSURE_BASELINE, v) == RT_EOK)
        {
            printf("success\n");
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT(set_sensor_oil_pressure_baseline, Set sensor oil pressure baseline)

void set_sensor_gear_distance_baseline(int argc, char** argv)
{
    if (argc == 2)
    {
        rt_uint32_t v = atoi(argv[1]);
        if (configuration_set_uint32(CONFIGURATION_SENSOR_GEAR_DISTANCE_BASELINE, v) == RT_EOK)
        {
            printf("success\n");
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT(set_sensor_gear_distance_baseline, Set sensor gear distance baseline)
void get_sensor_baseline()
{
    for (int i = CONFIGURATION_SENSOR_OIL_PRESSURE_BASELINE; i <= CONFIGURATION_SENSOR_OIL_PRESSURE_2_BASELINE; i++)
    {
        rt_uint32_t value = configuration_get_uint32(i);
        printf("%-32s: %lu\n", configuration_name(i), value);
    }
}
MSH_CMD_EXPORT(get_sensor_baseline, Get sensor baseline)

void set_axial_k_cli(int argc, char** argv)
{
    if (argc == 2)
    {
        char* str = argv[1];
        float v = atof(str);
        if (configuration_set_float(CONFIGURATION_AXIAL_K, v) == RT_EOK)
        {
            rt_kprintf("success: %f\n", v);
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT_ALIAS(set_axial_k_cli, set_axial_k, Set axial K);

void get_axial_k_cli()
{
    float v = configuration_get_float(CONFIGURATION_AXIAL_K);
    printf("%f\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_axial_k_cli, get_axial_k, Get axial K)

void set_axial_b_cli(int argc, char** argv)
{
    if (argc == 2)
    {
        float v = (float) atof(argv[1]);
        if (configuration_set_float(CONFIGURATION_AXIAL_B, v) == RT_EOK)
        {
            printf("success: %f\n", v);
            return;
        }
    }
    printf("fail\n");
}
MSH_CMD_EXPORT_ALIAS(set_axial_b_cli, set_axial_b, Set axial b);

void get_axial_b_cli()
{
    float v = configuration_get_float(CONFIGURATION_AXIAL_B);
    printf("%f\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_axial_b_cli, get_axial_b, Get axial b)

#include "drv_sensor.h"
void sensor_list_cli()
{
    for (int i = SENSOR_START; i < SENSOR_END; i++)
    {
        printf("%-32s: %d\n", sensor_name(i), i);
    }
}
MSH_CMD_EXPORT_ALIAS(sensor_list_cli, sensor_list, List sensors)

void sensor_read(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing sensor, %d - %d\n", SENSOR_START, SENSOR_END - 1);
        return;
    }
    int sensor = atoi(argv[1]);
    rt_uint32_t value = sensor_value(sensor);
    printf("%lu\n", value);
}
MSH_CMD_EXPORT(sensor_read, Sensor read);

void sensor_voltage_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing sensor\n");
        return;
    }
    int sensor = atoi(argv[1]);
    float value = sensor_voltage(sensor);
    printf("%f v\n", value);
}
MSH_CMD_EXPORT_ALIAS(sensor_voltage_cli, sensor_voltage, Sensor voltage)

void sensor_calibrate_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing sensor, %d - %d\n", SENSOR_START, SENSOR_END - 1);
        return;
    }
    int sensor = atoi(argv[1]);
    sensor_calibrate(sensor);
}
MSH_CMD_EXPORT_ALIAS(sensor_calibrate_cli, sensor_calibrate, Sensor calibrate)

void set_sensor_baseline_cli(int argc, char** argv)
{
    if (argc != 3)
    {
        printf("set_sensor_baseline <sensor> <value>\n");
        return;
    }
    int sensor = atoi(argv[1]);
    if (sensor < SENSOR_START || sensor >= SENSOR_END)
    {
        printf("Invalid sensor %d\n", sensor);
        return;
    }
    int value = atoi(argv[2]);
    configuration_e configuration = sensor_to_configuration(sensor);
    if (configuration == CONFIGRATION_END)
    {
        printf("Invalid sensor to configuration\n");
        return;
    }
    configuration_set_uint32(configuration, value);
}
MSH_CMD_EXPORT_ALIAS(set_sensor_baseline_cli, set_sensor_baseline, Set sensor baseline);

void sensor_axial_cli(int argc, char** argv)
{
    int sensor = SENSOR_END;
    if (argc != 2)
    {
        printf("Missing sensor\n");
        printf("oil pressure: %d\n", SENSOR_OIL_PRESSURE);
        printf("oil pressure 2: %d\n", SENSOR_OIL_PRESSURE_2);
        return;
    }
    sensor = atoi(argv[1]);
    if (sensor != SENSOR_OIL_PRESSURE && sensor != SENSOR_OIL_PRESSURE_2)
    {
        printf("Invalid sensor\n");
        printf("oil pressure: %d\n", SENSOR_OIL_PRESSURE);
        printf("oil pressure 2: %d\n", SENSOR_OIL_PRESSURE_2);
        return;
    }

    float v = sensor_axial(sensor);
    printf("%f\n", v);
}
MSH_CMD_EXPORT_ALIAS(sensor_axial_cli, sensor_axial, Sensor axial)

void sensor_distance_cli(int argc, char** argv)
{
    int sensor = SENSOR_END;
    if (argc != 2)
    {
        printf("Missing sensor\n");
        printf("putter: %d\n", SENSOR_PUTTER_DISTANCE);
        printf("gear: %d\n", SENSOR_GEAR_DISTANCE);
        return;
    }
    sensor = atoi(argv[1]);
    if (sensor != SENSOR_PUTTER_DISTANCE && sensor != SENSOR_GEAR_DISTANCE)
    {
        printf("Invalid sensor\n");
        printf("putter: %d\n", SENSOR_PUTTER_DISTANCE);
        printf("gear: %d\n", SENSOR_GEAR_DISTANCE);
        return;
    }

    float v = sensor_distance(sensor);
    printf("%f\n", v);
}
MSH_CMD_EXPORT_ALIAS(sensor_distance_cli, sensor_distance, Sensor distance)

#if 0
#include "mqtt.h"
void mqtt_pub_msg(int argc, char** argv)
{
    if (argc != 3)
    {
        printf("mqtt_pub <topic> <payload>\n");
        return;
    }
    mqtt_msg_t* msg = mqtt_msg_new_str(argv[1], argv[2]);
    mqtt_pub(&msg);
}
MBEDTLS_CIPHER_AES_128_CBCMD_EXPORT(mqtt_pub_msg, Mqtt publish);
#endif

#include "drv_relay.h"
void relay_list_cli()
{
    for (int i = RELAY_START; i < RELAY_END; i++)
    {
        printf("%-32s: %d\n", relay_name(i), i);
    }
}
MSH_CMD_EXPORT_ALIAS(relay_list_cli, relay_list, List relays)

void relay_on_cli(int argc, char **argv)
{
    if (argc != 2)
    {
        printf("Missing relay\n");
        return;
    }
    relay_on(atoi(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(relay_on_cli, relay_on, Relay on)

void relay_off_cli(int argc, char **argv)
{
    if (argc != 2)
    {
        printf("Missing relay\n");
        return;
    }
    relay_off(atoi(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(relay_off_cli, relay_off, Relay off)

#include "drv_panel.h"
void panel_list_cli()
{
    for (int i = PANEL_START; i < PANEL_END; i++)
    {
        printf("%-32s: %d\n", panel_name(i), i);
    }
}
MSH_CMD_EXPORT_ALIAS(panel_list_cli, panel_list, List panels)

void panel_on_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing panel\n");
        return;
    }
    panel_on(atoi(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(panel_on_cli, panel_on, Panel on)

void panel_off_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing panel\n");
        return;
    }
    panel_off(atoi(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(panel_off_cli, panel_off, Panel off)

#include "drv_lock_switch.h"
void lock_switch_list_cli()
{
    for (int i = LOCK_SWITCH_START; i < LOCK_SWITCH_END; i++)
    {
        printf("%-32s: %d\n", lock_switch_name(i), i);
    }
}
MSH_CMD_EXPORT_ALIAS(lock_switch_list_cli, lock_switch_list, List lock switches)

void lock_switch_read_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing lock switch\n");
        return;
    }
    int v = lock_switch_read(atoi(argv[1]));
    printf("%d\n", v);
}
MSH_CMD_EXPORT_ALIAS(lock_switch_read_cli, lock_switch_read, Read lock switch)

#include "rotate.h"
void get_auto_mode_baseline_cli()
{
    float v = auto_mode_baseline();
    printf("%f\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_auto_mode_baseline_cli, get_auto_mode_baseline, Get auto mode baseline);
void set_auto_mode_baseline_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing value\n");
        return;
    }
    auto_mode_set_baseline(atof(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(set_auto_mode_baseline_cli, set_auto_mode_baseline, Set auto mode baseline);

void get_auto_mode_percentage_cli()
{
    float v = auto_mode_percentage() * 100;
    printf("%f\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_auto_mode_percentage_cli, get_auto_mode_percentage, Get auto mode percentage);
void set_auto_mode_percentage_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing value\n");
        return;
    }
    auto_mode_set_percentage(atof(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(set_auto_mode_percentage_cli, set_auto_mode_percentage, Set auto mode percentage);

void get_auto_mode_update_interval_cli()
{
    rt_int32_t v = auto_mode_update_inverval();
    printf("%ld\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_auto_mode_update_interval_cli, get_auto_mode_update_interval, Get auto mode update interval);
void set_auto_mode_update_interval_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing value\n");
        return;
    }
    auto_mode_set_update_interval(atoi(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(set_auto_mode_update_interval_cli, set_auto_mode_update_interval, Set auto mode update interval);

void get_auto_mode_update_delay_cli()
{
    rt_int32_t v = auto_mode_update_delay();
    printf("%ld\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_auto_mode_update_delay_cli, get_auto_mode_update_delay, Get auto mode update delay);
void set_auto_mode_update_delay_cli(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing value\n");
        return;
    }
    auto_mode_set_update_delay(atoi(argv[1]));
}
MSH_CMD_EXPORT_ALIAS(set_auto_mode_update_delay_cli, set_auto_mode_update_delay, Set auto mode update delay);

#include "aliyun.h"
void get_aliyun_product_key_cli()
{
    const char* v = aliyun_product_key();
    printf("%s\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_aliyun_product_key_cli, get_aliyun_product_key, Get aliyun product key);

void get_aliyun_device_name_cli()
{
    const char* v = aliyun_device_name();
    printf("%s\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_aliyun_device_name_cli, get_aliyun_device_name, Get aliyun device name);

void get_aliyun_product_secret_cli()
{
    const char* v = aliyun_product_secret();
    printf("%s\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_aliyun_product_secret_cli, get_aliyun_product_secret, Get aliyun product secret);

void get_aliyun_device_secret_cli()
{
    const char* v = aliyun_device_secret();
    printf("%s\n", v);
}
MSH_CMD_EXPORT_ALIAS(get_aliyun_device_secret_cli, get_aliyun_device_secret, Get aliyun device secret);

#include <time.h>
#include <drv_pmhw.h>
int rtc_wakeup_test(int sleep_time)
{
    time_t now;

    HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1);
    stm32_pmtim_start(sleep_time);

    now = time(RT_NULL);    // 获取当前的系统时间
    rt_kprintf("%.*s", 25, ctime(&now));    // 打印系统时间

    return 0;
}
MSH_CMD_EXPORT(rtc_wakeup_test, rtc_wakeup_test);

void rt_pm_dump_status();
void standby_mode_test(int argc, char** argv)
{
    if (argc != 2)
    {
        printf("Missing sleep time\n");
        return;
    }
    int sleep_time = atoi(argv[1]);
    rtc_wakeup_test(sleep_time);  // 设置 RTC wakeup 时间

    rt_pm_request(PM_SLEEP_MODE_STANDBY);
    rt_pm_dump_status();
    rt_pm_module_get_status();

    rt_pm_release(PM_SLEEP_MODE_NONE);
    rt_pm_dump_status();
}
MSH_CMD_EXPORT(standby_mode_test, standby_mode_test);

#include "mcu_id.h"
void get_sn_cli()
{
    char sn[20] = { 0 };
    get_mcu_id(sn, sizeof(sn));
    printf("%s\n", sn);
}
MSH_CMD_EXPORT_ALIAS(get_sn_cli, get_sn, Get Sn)

#include "led_beep.h"
void led_beep_cli(int argc, char** argv)
{
    if (argc != 3)
    {
        printf("<led/beep> <on/off/normal1/normal2/alarm1/alarm2>\n");
        return;
    }
    led_notify_mode_e mode = LED_NOTIFY_MODE_OFF;
    if (strcmp(argv[2], "on") == 0)
    {
        mode = LED_NOTIFY_MODE_ON;
    }
    else if (strcmp(argv[2], "off") == 0)
    {
        mode = LED_NOTIFY_MODE_OFF;
    }
    else if (strcmp(argv[2], "normal1") == 0)
    {
        mode = LED_NOTIFY_MODE_NORMAL_1;
    }
    else if (strcmp(argv[2], "normal2") == 0)
    {
        mode = LED_NOTIFY_MODE_NORMAL_2;
    }
    else if (strcmp(argv[2], "alarm1") == 0)
    {
        mode = LED_NOTIFY_MODE_ALARM_1;
    }
    else if (strcmp(argv[2], "alarm2") == 0)
    {
        mode = LED_NOTIFY_MODE_ALARM_2;
    }
    else
    {
        printf("Invalid mode: %s\n", argv[2]);
        return;
    }

    led_beep_e l;
    if (strcmp(argv[1], "panel_yellow") == 0)
    {
        l = PANEL_LED_YELLOW;
    }
    else if (strcmp(argv[1], "panel_green") == 0)
    {
        l = PANEL_LED_GREEN;
    }
    else if (strcmp(argv[1], "panel_red") == 0)
    {
        l = PANEL_LED_RED;
    }
    else if (strcmp(argv[1], "beep") == 0)
    {
        l = PANEL_BEE;
    }
    else
    {
        printf("Invalid led/beep: %s\n", argv[1]);
        return;
    }

    led_beep(l, mode);
}
MSH_CMD_EXPORT_ALIAS(led_beep_cli, led_beep, Led and Beep)
